#ifndef __CORE_COMMON_GLOBAL_H_INCLUDE__
#define __CORE_COMMON_GLOBAL_H_INCLUDE__

#include <core/common/platform.h>

namespace core{ namespace common
{
	// bytes
	static const uint64 kByteUnitsPerKilo   = 1024;
	static const uint64 kKiloUnitsPerMega   = 1024;
	static const uint64 kMegaUnitsPerGiga   = 1024;
	static const uint64 kByteUnitsPerMega   = kByteUnitsPerKilo * kKiloUnitsPerMega;
	static const uint64 kByteUnitsPerGiga   = kByteUnitsPerMega * kMegaUnitsPerGiga;
	static const uint64 kByteUnitsPerTera   = kByteUnitsPerMega * kByteUnitsPerGiga;
	
	// seconds
	static const int64  kMilliUnitsPerSec   = 1000;
	static const int64  kMicroUnitsPerMilli = 1000;
	static const int64  kNanoUnitsPerMicro  = 1000;
	static const int64  kMicroUnitsPerSec   = kMicroUnitsPerMilli * kMilliUnitsPerSec;
	static const int64  kNanoUnitsPerSec    = kNanoUnitsPerMicro * kMicroUnitsPerSec;

	static const time_t kSecondUnitsPerMinute = 60;
	static const time_t KMinuteUnitsPerHour   = 60;
	static const time_t kHourUnitsPerDay      = 24;
	static const time_t kSecondUnitsPerHour   = kSecondUnitsPerMinute * KMinuteUnitsPerHour;
	static const time_t kSecondUnitsPerDay    = kSecondUnitsPerHour * kHourUnitsPerDay;
	
	// low-high
	static const uint64 kLow32BitsMask  = 0xffffffffULL;
	static const uint64 kHigh32BitsMask = 0xffffffff00000000ULL;

	static const uint64 kMemoryPageSize = 4096; // Intel x86

	// system relative
	CORE_COMMON_API__ int64  getMicroTime();
	CORE_COMMON_API__ int64  getHighResolutionTime();
	CORE_COMMON_API__ int64  erfTime2MicroTime( uint64 erfTime , bool unixTime = true );
	CORE_COMMON_API__ uint64 microTime2ErfTime( int64 microTime, bool unixTime = true );
	CORE_COMMON_API__ time_t getLocalTimezoneSeconds();
	CORE_COMMON_API__ bool   getGmtTimestamp( time_t timestamp, struct tm &timeValue );
	CORE_COMMON_API__ bool   getLocalTimestamp( time_t timestamp, struct tm &timeValue );
	CORE_COMMON_API__ void   milliSleep( int milliSecs );
	CORE_COMMON_API__ void   microSleep( int microSecs );
	CORE_COMMON_API__ std::string getWorkingDirectory();
	CORE_COMMON_API__ bool   setWorkingDirectory( const std::string &directory );
	CORE_COMMON_API__ size_t getProcessId();
	CORE_COMMON_API__ size_t getThreadId();
	CORE_COMMON_API__ bool getEnvironmentVariable( const std::string &name, std::string &strValue );
	CORE_COMMON_API__ bool getEnvironmentVariable( const std::string &name, std::vector<std::string> &nValues );

	// general error code
	CORE_COMMON_API__ uint32 getErrorCode();
	CORE_COMMON_API__ void   setErrorCode( uint32 code );
	CORE_COMMON_API__ std::string getErrorDescription( uint32 code = -1 );
	
	// network error code
	CORE_COMMON_API__ uint32 getNetworkErrorCode();
	CORE_COMMON_API__ void   setNetworkErrorCode( uint32 code );
	CORE_COMMON_API__ std::string getNetworkErrorDescription( uint32 code = -1 );

	// dynamic library
	CORE_COMMON_API__ void *loadDynamicLibrary( const std::string &file, int mode = -1 );
	CORE_COMMON_API__ bool  freeDynamicLibrary( void *libModule );
	CORE_COMMON_API__ void *getDynamicSymbol( void *libModule, const std::string &name );
	CORE_COMMON_API__ std::string getDynamicLibraryError();

	// system control
	CORE_COMMON_API__ void exit( int nCode );

	template<class T> const T minValue( const T n1, const T n2 ){ return n1 < n2 ? n1 : n2; }
	template<class T> const T maxValue( const T n1, const T n2 ){ return n1 > n2 ? n1 : n2; }
	template<class T> const T absValue( const T n ){ return n >= 0 ? n : -n; }
	template<class T> const T limitValue( const T n, const T low, const T high )
	{
		if( n < low )
		{
			return low; 
		}
		else if( n > high )
		{
			return high;
		}

		return n;
	}

	// reverse byte endian
	CORE_COMMON_API__ uint32 reverseEndian( const uint32 number );
	
	// network order to host order
	CORE_COMMON_API__ uint16 network2Host16( uint16 number );
	CORE_COMMON_API__ uint32 network2Host32( uint32 number );
	CORE_COMMON_API__ uint64 network2Host64( uint64 number );
	
	// host order to network order
	CORE_COMMON_API__ uint16 host2Network16( uint16 number );
	CORE_COMMON_API__ uint32 host2Network32( uint32 number );
	CORE_COMMON_API__ uint64 host2Network64( uint64 number );

	typedef std::list<int> IntegerList;
	typedef std::list<int64> BigIntegerList;
	typedef std::vector<int> IntegerArray;
	typedef std::vector<int64> BigIntegerArray;
	typedef std::set<int> IntegerSet;
	typedef std::set<int64> BigIntegerSet;
}}

#endif //__CORE_COMMON_GLOBAL_H_INCLUDE__
